const nbsp = String.fromCharCode(160)

function handleString(value: string) {
  if (value != null) {
    value = value.replace(/\\\\/g, '\\')
    value = value.replace(/\\r/g, '\r')
    value = value.replace(/\\n/g, '\n')
    return value
  } else {
    return ''
  }
}

// 变量: variables = new Map([['name', 'Alice']])
// 输入: value = "Hello ${name}!${nbsp}"
// 输出: "Hello Alice!\u00A0"
export function xlateArgument(value: string, variables: any) {
  value = value.replace(/^\s+/, '')
  value = value.replace(/\s+$/, '')
  let r2
  let parts = []
  if (/\$\{/.exec(value)) {
    const regexp = /\$\{(.*?)\}/g
    let lastIndex = 0
    while ((r2 = regexp.exec(value))) {
      if (variables.has(r2[1])) {
        if (r2.index - lastIndex > 0) {
          parts.push(handleString(value.substring(lastIndex, r2.index)))
        }
        parts.push(variables.get(r2[1]))
        lastIndex = regexp.lastIndex
      } else if (r2[1] == 'nbsp') {
        if (r2.index - lastIndex > 0) {
          parts.push(
            variables.get(handleString(value.substring(lastIndex, r2.index)))
          )
        }
        parts.push(nbsp)
        lastIndex = regexp.lastIndex
      }
    }
    if (lastIndex < value.length) {
      parts.push(handleString(value.substring(lastIndex, value.length)))
    }
    return parts.map(String).join('')
  } else {
    return handleString(value)
  }
}

// 变量: variables = new Map([['x', 10], ['y', 20]])
// 输入: script = "${x} + ${y} * ${x}"
// 输出: {
//   script: "arguments[0] + arguments[1] * arguments[0]",
//   argv: [10, 20]
// }
// const func = new Function('arguments', 'return ' + script);
// func(argv); // 返回 10 + 20 * 10 = 210
// 插值脚本
export function interpolateScript(script: string, variables: any) {
  let value = script.replace(/^\s+/, '').replace(/\s+$/, '')
  let r2
  let parts = []
  const variablesUsed: any = {}
  const argv: any[] = []
  let argl = 0 // length of arguments
  if (/\$\{/.exec(value)) {
    const regexp = /\$\{(.*?)\}/g
    let lastIndex = 0
    while ((r2 = regexp.exec(value))) {
      const variableName = r2[1]
      if (variables.has(variableName)) {
        if (r2.index - lastIndex > 0) {
          parts.push(handleString(value.substring(lastIndex, r2.index)))
        }
        if (!variablesUsed.hasOwnProperty(variableName)) {
          variablesUsed[variableName] = argl
          argv.push(variables.get(variableName))
          argl++
        }
        parts.push(`arguments[${variablesUsed[variableName]}]`)
        lastIndex = regexp.lastIndex
      }
    }
    if (lastIndex < value.length) {
      parts.push(handleString(value.substring(lastIndex, value.length)))
    }
    return {
      script: parts.join(''),
      argv,
    }
  } else {
    return {
      script: handleString(value),
      argv,
    }
  }
}


